package com.smitish.vueblog.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.smitish.vueblog.common.dto.LoginDto;
import com.smitish.vueblog.common.dto.RegisterDto;
import com.smitish.vueblog.common.lang.Result;
import com.smitish.vueblog.entity.Logs;
import com.smitish.vueblog.entity.User;
import com.smitish.vueblog.service.LogsService;
import com.smitish.vueblog.service.UserService;
import com.smitish.vueblog.util.JwtUtils;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class AccountController {
    // 注入
    @Autowired
    UserService userService;

    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    LogsService logsService;

    /**
     * 登录函数
     *
     * @param loginDto 提交过来的数据
     * @param response 返回时候带着Authorization Token
     * @return 返回个人登录数据
     */
    @PostMapping("/login")
    public Result login(@Validated @RequestBody LoginDto loginDto, HttpServletResponse response) {
        User user = userService.getOne(new QueryWrapper<User>().eq("username", loginDto.getUsername()));
        Assert.notNull(user, "用户名或密码不正确");

        if (!user.getPassword().equals(SecureUtil.md5(loginDto.getPassword()))) {
            return Result.fail("用户名或密码不正确");
        }
        String jwt = jwtUtils.generateToken(user.getId());
        // 将jwt放入header
        response.setHeader("Authorization", jwt);
        response.setHeader("Access-control-Expose-Headers", "Authorization");


        return Result.success(MapUtil.builder()
                .put("id", user.getId())
                .put("username", user.getUsername())
                .put("avatar", user.getAvatar())
                .put("email", user.getEmail())
                .put("description", user.getDescription()).map()
        );
    }


    /**
     * 注册api
     *
     * @param user 用户实体
     * @return 返回注册结果
     */
    @PostMapping("/register")
    public Result register(@Validated @RequestBody User user) {
        User user1 = userService.getOne(new QueryWrapper<User>().eq("username", user.getUsername()));
        Assert.isNull(user1, "用户名已存在");
        User username = userService.getOne(new QueryWrapper<User>().eq("email", user.getEmail()));
        Assert.isNull(username, "邮箱已存在");
        user.setPassword(SecureUtil.md5(user.getPassword()));
        user.setStatus(0);
        user.setDescription("我是花生猫,我来到了Smitish博客平台啦！");

        if (userService.saveOrUpdate(user)) {
            // 需要将注册的用户信息返回过来
            User temp = userService.getOne(new QueryWrapper<User>()
                    .eq("username", user.getUsername()));
            System.out.println(temp);
            // 注册成功需要将动态写入日志
            Logs logs = new Logs();
            logs.setUserId(temp.getId());
            logs.setLogContent("注册了账号");
            System.out.println(logs);
            logsService.saveOrUpdate(logs);
            return Result.succ(200, "注册成功", null);
        }

        return Result.fail("注册失败！");
    }


    /**
     * 退出登录 销毁本地token
     *
     * @return 退出信息
     */
    @RequiresAuthentication
    @GetMapping("/logout")
    public Result logout() {
        SecurityUtils.getSubject().logout();
        return Result.success("退出登入成功！", null);
    }
}
